#include "bsp.h"
#include "gpio/_gpio.h"
#include "ti_msp_dl_config.h"
#include "stdlib.h"
#include "OLED/oled.h"

key_t key1;
key_t key2;
key_t key3;
key_t key4;

usart_t usart0;
usart_t usart1;

motor_t motor_1;
motor_t motor_2;

led_t user_led;

line_flw_t my_line_flw;

void key_init();
void usart_init();
void motor_init();
void led_init();
void line_flw_init();

void bsp_init()
{
    SYSCFG_DL_init();
    // uart init
    NVIC_ClearPendingIRQ(UART_0_INST_INT_IRQN);
    NVIC_EnableIRQ(UART_0_INST_INT_IRQN);
    usart_init();

    NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN);
    DL_TimerG_startCounter(TIMER_0_INST);
    
    // app/module init
    key_init();
    OLED_Init();
    motor_init();
    led_init();
    line_flw_init();
}

void usart_init()
{
    usart0.uartx = UART_0_INST;

    usart1.uartx = UART_1_INST;
}

void key_init()
{
    key1.gpio = malloc(sizeof(gpio_t));
    key1.gpio->gpiox = KEY_GROUP_KEY_1_PORT;
    key1.gpio->pinx = KEY_GROUP_KEY_1_PIN;
    key1.pressed_state = 0;

    key2.gpio = malloc(sizeof(gpio_t));
    key2.gpio->gpiox = KEY_GROUP_KEY_2_PORT;
    key2.gpio->pinx = KEY_GROUP_KEY_2_PIN;
    key2.pressed_state = 0;

    key3.gpio = malloc(sizeof(gpio_t));
    key3.gpio->gpiox = KEY_GROUP_KEY_3_PORT;
    key3.gpio->pinx = KEY_GROUP_KEY_3_PIN;
    key3.pressed_state = 0;

    key4.gpio = malloc(sizeof(gpio_t));
    key4.gpio->gpiox = KEY_GROUP_KEY_4_PORT;
    key4.gpio->pinx = KEY_GROUP_KEY_4_PIN;
    key4.pressed_state = 0;
}

void motor_init()
{
    motor_1.dir1 = malloc(sizeof(gpio_t));
    motor_1.dir2 = malloc(sizeof(gpio_t));
    motor_1.dir1->gpiox = MOTOR_CTRL_GROUP_M1_DIR1_PORT;
    motor_1.dir2->gpiox = MOTOR_CTRL_GROUP_M1_DIR2_PORT;
    motor_1.dir1->pinx = MOTOR_CTRL_GROUP_M1_DIR1_PIN;
    motor_1.dir2->pinx = MOTOR_CTRL_GROUP_M1_DIR2_PIN;
    motor_1.timer_inst = MOTOR_SPD_CTRL_INST;
    motor_1.cc_index = GPIO_MOTOR_SPD_CTRL_C0_IDX;

    motor_2.dir1 = malloc(sizeof(gpio_t));
    motor_2.dir2 = malloc(sizeof(gpio_t));
    motor_2.dir1->gpiox = MOTOR_CTRL_GROUP_M2_DIR1_PORT;
    motor_2.dir2->gpiox = MOTOR_CTRL_GROUP_M2_DIR2_PORT;
    motor_2.dir1->pinx = MOTOR_CTRL_GROUP_M2_DIR1_PIN;
    motor_2.dir2->pinx = MOTOR_CTRL_GROUP_M2_DIR2_PIN;
    motor_2.timer_inst = MOTOR_SPD_CTRL_INST;
    motor_2.cc_index = GPIO_MOTOR_SPD_CTRL_C1_IDX;

    // enable motor
    DL_TimerG_startCounter(MOTOR_SPD_CTRL_INST);

    // enable encoder
    NVIC_ClearPendingIRQ(ENCODER_GROUP_GPIOB_INT_IRQN);
    NVIC_ClearPendingIRQ(ENCODER_GROUP_GPIOA_INT_IRQN);
    NVIC_EnableIRQ(ENCODER_GROUP_GPIOB_INT_IRQN);
    NVIC_EnableIRQ(ENCODER_GROUP_GPIOA_INT_IRQN);
}

void led_init()
{
    user_led.led_ctrl = malloc(sizeof(gpio_t));
    user_led.led_ctrl->gpiox = LED_PORT;
    user_led.led_ctrl->pinx = LED_USER_LED_PIN;
    user_led.on_state = 1;
}

void line_flw_init()
{
    for (int i = 0; i < 12; i++)
    {
        my_line_flw.pins[i] = malloc(sizeof(key_t));
        my_line_flw.pins[i]->gpio = malloc(sizeof(gpio_t));
        my_line_flw.pins[i]->pressed_state = 1;
    }

    my_line_flw.pins[0]->gpio->gpiox = LINE_FLW_GROUP_PIN_0_PORT;
    my_line_flw.pins[0]->gpio->pinx  = LINE_FLW_GROUP_PIN_0_PIN;

    my_line_flw.pins[1]->gpio->gpiox = LINE_FLW_GROUP_PIN_1_PORT;
    my_line_flw.pins[1]->gpio->pinx  = LINE_FLW_GROUP_PIN_1_PIN;

    my_line_flw.pins[2]->gpio->gpiox = LINE_FLW_GROUP_PIN_2_PORT;
    my_line_flw.pins[2]->gpio->pinx  = LINE_FLW_GROUP_PIN_2_PIN;

    my_line_flw.pins[3]->gpio->gpiox = LINE_FLW_GROUP_PIN_3_PORT;
    my_line_flw.pins[3]->gpio->pinx  = LINE_FLW_GROUP_PIN_3_PIN;

    my_line_flw.pins[4]->gpio->gpiox = LINE_FLW_GROUP_PIN_4_PORT;
    my_line_flw.pins[4]->gpio->pinx  = LINE_FLW_GROUP_PIN_4_PIN;

    my_line_flw.pins[5]->gpio->gpiox = LINE_FLW_GROUP_PIN_5_PORT;
    my_line_flw.pins[5]->gpio->pinx  = LINE_FLW_GROUP_PIN_5_PIN;

    my_line_flw.pins[6]->gpio->gpiox = LINE_FLW_GROUP_PIN_6_PORT;
    my_line_flw.pins[6]->gpio->pinx  = LINE_FLW_GROUP_PIN_6_PIN;

    my_line_flw.pins[7]->gpio->gpiox = LINE_FLW_GROUP_PIN_7_PORT;
    my_line_flw.pins[7]->gpio->pinx  = LINE_FLW_GROUP_PIN_7_PIN;

    my_line_flw.pins[8]->gpio->gpiox = LINE_FLW_GROUP_PIN_8_PORT;
    my_line_flw.pins[8]->gpio->pinx  = LINE_FLW_GROUP_PIN_8_PIN;

    my_line_flw.pins[9]->gpio->gpiox = LINE_FLW_GROUP_PIN_9_PORT;
    my_line_flw.pins[9]->gpio->pinx  = LINE_FLW_GROUP_PIN_9_PIN;

    my_line_flw.pins[10]->gpio->gpiox = LINE_FLW_GROUP_PIN_10_PORT;
    my_line_flw.pins[10]->gpio->pinx  = LINE_FLW_GROUP_PIN_10_PIN;

    my_line_flw.pins[11]->gpio->gpiox = LINE_FLW_GROUP_PIN_11_PORT;
    my_line_flw.pins[11]->gpio->pinx  = LINE_FLW_GROUP_PIN_11_PIN;

}
